package com.xiayuxuanmin.weixinpay.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

/**
 * @Author xiayuxuanmin
 * @Date 2019/8/10
 * @Description
 */
public class ZxingUtil {

    /**
     * Zxing图形码生成工具类
     * @param contents 内容
     * @param format 图片格式(png,jpg,bmp)
     * @param width 二维码宽度
     * @param height 二维码高度
     * @param saveImagePath 存储二维码图片的完整路径,包含文件名
     * @return
     */
    public static Boolean encode (String contents,String format,int width,int height,String saveImagePath){
        Boolean bool = false;
        BufferedImage image = createImage(contents,width,height);
        if(image != null){
            bool = writeToFile(image,format,saveImagePath);
        }
        return bool;
    }

    public static void encode (String contents,int width,int height){
        createImage(contents,width,height);
    }

    /**
     * 生成二维码图片
     * @param contents 二维码内容
     * @param width 生成的二维码图片宽度
     * @param height 生成的二维码图片高度
     * @return
     */
    public static BufferedImage createImage(String contents,int width,int height){
        BufferedImage bufImg = null;
        Map<EncodeHintType,Object> hints = new HashMap<>();
        //指定纠错级别(L--7%,M--15%,Q--25%,H--30%)
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //ncodeHintType.MARGIN设置zxing二维码空白区域大小
        hints.put(EncodeHintType.MARGIN,10);
        //指定编码格式
        hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
        try {
            //生成的二维码图片默认背景为白色,前景为黑色,但是在加入logo图像后会导致logo也变为黑白色,至于是什么原因还没有仔细去读它的源码
            //所以这里对其第一个参数黑色将ZXing默认的前景色0xFF000000稍微改了一下0xFF000001,最终效果也是白色背景黑色前景的二维码,且logo颜色保持原有不变
            BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
            //这里要显式指定MatrixToImageConfig,否则还会按照默认处理将logo图像也变为黑白色
            //(如果打算加logo的话,反之则不须传MatrixToImageConfig参数)
            MatrixToImageConfig config = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);
            bufImg = MatrixToImageWriter.toBufferedImage(bitMatrix, config);
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return  bufImg;
    }

    /**
     * 将 BufferedImage 图片对象写入文件
     * @param bufImg BufferedImage 对象
     * @param format 图片格式(png,jpg,bmp)
     * @param saveImagePath 存储图片的完整路径,包含文件名
     * @return
     */
    @SuppressWarnings("finally")
    public static Boolean writeToFile(BufferedImage bufImg,String format,String saveImagePath){
        Boolean bool = false;
        try {
            bool = ImageIO.write(bufImg, format, new File(saveImagePath));
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            return bool;
        }
    }
}